package vek.GUI;

import vek.GUI.SearchAndListView.KeyboardView;
import vek.GUI.SearchAndListView.NavigationPanel;
import vek.GUI.SearchAndListView.RightPanelView;
import vek.GUI.MapView.LayerHandler;
import vek.GUI.MapView.Background;
import vek.GUI.MapView.ScrollableView;
import vek.GUI.MapView.MarkingsView;
import vek.GUI.Infoview.InfoView;

import javax.swing.*;
import java.awt.Dimension;
import java.awt.*;
import java.awt.Dimension;
import java.awt.BorderLayout;
import vek.ObjectDatabase.DatabaseConnector;
import vek.controllers.SearchAndList.KeyboardSubPanelController;
import vek.controllers.SearchAndList.KeyboardMainController;
import vek.controllers.Map.MarkingsViewController;
import vek.controllers.SearchAndList.NavigationPanelController;
import vek.controllers.SearchAndList.RightPanelViewController;

/**
 *  This Class creates all the GUI elements of the program and the main JFrame.
 *  This class is the JFrame which contains all the other GUI components.
 *  This Class extends from JFrame which is part of the Swing family.
 * @author Christian, Michal og Jakob (Hold 1, gruppe 2)
 */

public class MainWindow extends JFrame{

    
    // databaseConnector
    private DatabaseConnector databaseConnector;
    
    //Fields
    private Container mainContainer; // the container which keeps track of the Components. Is used to add/remove JComponents.
    
    //controllers
    
    //sizes of Jcomponents
    private Dimension screenSize; // the size of the screen in pixels
    private Dimension sizeOfComponentsInScrollableView; // the size of the components which are placed inside the scroll view
    private Dimension sizeOfScrollableView;
    private Dimension sizeOfNaivationPanel;
    
    //components
    private KeyboardView navigationKeyboard;
    private RightPanelView rightPanelView;
    private NavigationPanel navigationPanel;
    private ScrollableView scrollView;
    private InfoView infoView;
    private CentralPanelView centralPanelView;
    private LayerHandler jlayeredPane;
    private MarkingsView markingsView;
    private Background background;
    private JPanel bottomPanel;
    
    //controllers
    private KeyboardSubPanelController keyboardController; // the controller which controls the input from the On-screen keyboard
    private MarkingsViewController markingsViewController; // the controller which controls the clicks on the Marking view buttons
    private NavigationPanelController naviController; // the controller that controls the search function
    private RightPanelViewController rightPanelViewController; // the controller that controls the rightPanelView, that is it controls the clicks on the POIs
    
    private Image backgroundImage; // the background image to be used in the main scroll view
    
    private boolean isFullScreen; // is the JFrame full screen
    
    
    /**
     * Constructor that runs all the other methods in this class to create all the JComponents.
     * @param sizeScrollView the size of the main ScrollView where the map is
     * @param sizeOfCompInScrollView size of the Components, mainly the size of the background image.
     * @param backIm the background image which is placed inside the ScrollView. This is the map of the city which this Terminal is placed in
     * @param dbc The database connector used
     */
    public MainWindow(Dimension sizeScrollView, 
            Dimension sizeOfCompInScrollView, Image backIm, DatabaseConnector dbc)
    {
        //Object creation
        backgroundImage = backIm;
        sizeOfScrollableView = sizeScrollView;
        sizeOfComponentsInScrollableView = sizeOfCompInScrollView;
        screenSize = new Dimension(
                (int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth() ),
                (int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight() ));
        sizeOfNaivationPanel = new Dimension((int)screenSize.getWidth(), (int)(screenSize.getHeight() * 0.15) );
        databaseConnector = dbc;
        
        
        
        mainContainer = getContentPane();
        
        createComponents();
        createLayout();
        setBoundsOfComponentsInScrollView();
        addContentToContainer();
        addObserversToDatabaseConnector();
        
        
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //setPreferredSize(screenSize);
        
        //mainContainer.setLayout();
        
        //toggleFullScreen();

        //validate();
        pack();
        
        setVisible(true);       
        
    }
    
    /**
     * Sets the bounds of the components in the scroll view, this is done since the layout used there is the null layout.
     */

    private void setBoundsOfComponentsInScrollView()
    {
       int w = (int)sizeOfComponentsInScrollableView.getWidth();
       int h = (int)sizeOfComponentsInScrollableView.getHeight();
       background.setBounds(0, 0, w, h);
       markingsView.setBounds(0, 0, w, h);
    }

    /**
     * Creates the JComponents in a specific order, also calls createRightPanelComponents() and createNavigationPanelComponents()
     */
    
    private void createComponents()
    {
        createRightPanelComponents();
        createNavigationPanelComponents();
        
        infoView = new InfoView(new Dimension((int)screenSize.getWidth(), (int)(screenSize.getHeight() * 0.3)), screenSize, this);
        markingsViewController = new MarkingsViewController(infoView, databaseConnector);
        markingsView = new MarkingsView(sizeOfComponentsInScrollableView, markingsViewController, databaseConnector);
        background = new Background(backgroundImage, sizeOfComponentsInScrollableView);
        jlayeredPane = new LayerHandler(sizeOfComponentsInScrollableView, markingsView, background);
        scrollView = new ScrollableView(sizeOfScrollableView, sizeOfComponentsInScrollableView, jlayeredPane, screenSize);
        centralPanelView = new CentralPanelView(sizeOfScrollableView, scrollView, infoView, screenSize);
        
        rightPanelViewController.setScrollView(scrollView);
    }
    
    /**
     * creates the JComponents in the NavigationPanel, that is the JComponents in the bottom of the screen
     */
    
    private void createNavigationPanelComponents()
    {
        bottomPanel = new JPanel();
        bottomPanel.setPreferredSize(sizeOfNaivationPanel);
        navigationPanel = new NavigationPanel(sizeOfNaivationPanel);
        naviController = new NavigationPanelController(databaseConnector, rightPanelViewController, navigationPanel);
        
        KeyboardMainController kpmc = new KeyboardMainController(naviController);
        navigationKeyboard = new KeyboardView(sizeOfNaivationPanel, naviController, kpmc);
        keyboardController = new KeyboardSubPanelController(navigationKeyboard, naviController);
        
        kpmc.setKeyboardView(navigationKeyboard);
        navigationKeyboard.setController(keyboardController);
        naviController.setKeyboardView(navigationKeyboard);
        navigationPanel.setController(naviController);
        
        
        bottomPanel.add(navigationKeyboard);
        bottomPanel.add(navigationPanel);

    }
    
    /**
     * creates the JComponents in the NavigationPanel, that is the JComponents at the right the screen
     */
    
    private void createRightPanelComponents()
    {
        rightPanelView = new RightPanelView(screenSize);
        rightPanelViewController = new RightPanelViewController(rightPanelView);
        rightPanelView.setController(rightPanelViewController);
    }
    
    /**
     * adds observers to the database connector
     */
    
    private void addObserversToDatabaseConnector()
    {
        databaseConnector.addObserver(markingsView);
    }
    
    /**
     * Sets the JFrame to be pseudo full screen.
     */
    
    private void toggleFullScreen() // code inspired by http://www.javaworld.com/javaforums/showflat.php?Cat=&Board=javabeginner&Number=30686&page=4&view=collapsed&sb=11&o=&fpart=1
    {
        if(isFullScreen)
        {
            setUndecorated(false);
            setPreferredSize(screenSize);
            isFullScreen = false;
        }
        
        else
        {
            setUndecorated(true);
            //setExtendedState(Frame.MAXIMIZED_BOTH);
            setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
            isFullScreen = true;
        }
        
    }
    
    /**
     * sets the layout for this JFrame
     */
    
    private void createLayout()
    {
       setLayout(new BorderLayout());
    }
    
    /**
     * Adds the content to the container, that is makes the JComponents visible in the JFrame.
     */

    private void addContentToContainer()
    {     
       mainContainer.add(centralPanelView, BorderLayout.CENTER);
       mainContainer.add(rightPanelView, BorderLayout.EAST);
       mainContainer.add(bottomPanel, BorderLayout.SOUTH);       
    }
}
